
#include "cybertron/network/NetworkActionBase.hpp"
#include "cybertron/network/Message.hpp"

CYBERTRON_BEGIN

CybertronCoreAPI NetworkActionBase::NetworkActionBase()
{
	zeroMembers();
}

CybertronCoreAPI NetworkActionBase::~NetworkActionBase()
{
	setEnd();
}

void NetworkActionBase::zeroMembers()
{
	mStarted = false;
	mEnded = false;
	mDesiredMessageId = 0;
	mMillisecondsPassed = 0;
	mMillisecondsTimeout = -1;
}

CybertronCoreAPI void NetworkActionBase::setTimeout(int millisecondsTimeout)
{
	mMillisecondsTimeout = millisecondsTimeout;
}

CybertronCoreAPI int NetworkActionBase::getTimeout() const
{
	return mMillisecondsTimeout;
}

CybertronCoreAPI void NetworkActionBase::setSocket(std::shared_ptr<SocketBase> pSocket)
{
	mpSocket = pSocket;
}

CybertronCoreAPI void NetworkActionBase::setDesiredMessageId(std::uint16_t desiredMessageId)
{
	mDesiredMessageId = desiredMessageId;
}

CybertronCoreAPI void NetworkActionBase::setStart()
{
	if (mStarted)
	{
		return;
	}

	mStarted = true;
	mMillisecondsPassed = 0;

	onStart();
}

CybertronCoreAPI void NetworkActionBase::setEnd()
{
	if (mEnded)
	{
		return;
	}

	mEnded = true;

	onEnd();
}

CybertronCoreAPI void NetworkActionBase::handleTimer(int ms)
{
	if (!mStarted)
	{
		return;
	}
	if (mEnded)
	{
		return;
	}

	mMillisecondsPassed += ms;
	if (mMillisecondsTimeout >= 0)
	{
		if (mMillisecondsPassed >= mMillisecondsTimeout)
		{
			onTimeout();

			setEnd();

			return;
		}
	}

	onTimer(ms);
}

CybertronCoreAPI void NetworkActionBase::handleMessage(Message& msg)
{
	if (!mStarted)
	{
		return;
	}
	if (mEnded)
	{
		return;
	}

	bool gotDesiredMessage = false;
	if (mDesiredMessageId != 0)
	{
		if (msg.parseMsgId() == mDesiredMessageId)
		{
			gotDesiredMessage = true;
		}
	}

	if (gotDesiredMessage)
	{
		onDesiredMessage(msg);
	}
	else
	{
		onMessage(msg);
	}

	if (gotDesiredMessage)
	{
		setEnd();
	}
}

CybertronCoreAPI bool NetworkActionBase::getStarted() const
{
	return mStarted;
}

CybertronCoreAPI bool NetworkActionBase::getEnded() const
{
	return mEnded;
}

CybertronCoreAPI int NetworkActionBase::getMillisecondsPassed() const
{
	return mMillisecondsPassed;
}

CybertronCoreAPI std::uint16_t NetworkActionBase::getDesiredMessageId() const
{
	return mDesiredMessageId;
}

CybertronCoreAPI std::shared_ptr<SocketBase> NetworkActionBase::getSocket() const
{
	return mpSocket.lock();
}

CybertronCoreAPI void NetworkActionBase::onStart()
{
	// do nothing.
}

CybertronCoreAPI void NetworkActionBase::onTimer(int ms)
{
	// do nothing.
}

CybertronCoreAPI void NetworkActionBase::onTimeout()
{
	// do nothing.
}

CybertronCoreAPI void NetworkActionBase::onDesiredMessage(Message& msg)
{
	// do nothing.
}

CybertronCoreAPI void NetworkActionBase::onMessage(Message& msg)
{
	// do nothing.
}

CybertronCoreAPI void NetworkActionBase::onEnd()
{
	// do nothing.
}

CYBERTRON_END
